<template>
  <div v-if="replies?.length" class="comment-replies">
    <DynamicVirtualList
      v-if="replies.length > virtualListThreshold"
      ref="virtualListRef"
      :data="visibleReplies"
      :estimated-height="100"
      :buffer="2"
      item-key="id"
      :reset-scroll-on-data-change="false"
    >
      <template #default="{ item }">
        <CommentReplyItem
          :reply="item as CommentReply"
          :comment-id="commentId"
          :current-user-id="currentUserId"
          :is-resolved="isResolved"
          :class="{
            'highlighted-reply': highlightedReplyId === (item as CommentReply).id,
          }"
          @reply="handleReply"
          @quote="handleQuote"
          @quote-click="handleQuoteClick"
          @updated="handleUpdated"
        />
      </template>
    </DynamicVirtualList>
    <template v-else>
      <CommentReplyItem
        v-for="reply in visibleReplies"
        :key="reply.id"
        :reply="reply"
        :comment-id="commentId"
        :current-user-id="currentUserId"
        :is-resolved="isResolved"
        :class="{ 'highlighted-reply': highlightedReplyId === reply.id }"
        @reply="handleReply"
        @quote="handleQuote"
        @quote-click="handleQuoteClick"
        @updated="handleUpdated"
      />
    </template>
    <div v-if="shouldShowExpandButton" class="reply-expand-actions">
      <el-button
        v-if="!isAllRepliesVisible"
        size="small"
        text
        @click="handleExpandReplies"
      >
        展开更多
      </el-button>
      <el-button
        v-if="isAllRepliesVisible && visibleCount > DEFAULT_REPLY_COUNT"
        size="small"
        text
        @click="handleCollapseReplies"
      >
        收起
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, nextTick, onBeforeUnmount } from "vue";
import { DynamicVirtualList } from "../virtual/index";
import CommentReplyItem from "./CommentReplyItem.vue";
import type { CommentReply } from "../../types/comment";

defineOptions({
  name: "CommentList",
});

const props = defineProps<{
  replies: CommentReply[];
  commentId: string; // 批注ID，用于管理展开状态
  currentUserId?: string; // 当前用户ID
  highlightedReplyId?: string; // 高亮的回复ID
  isResolved?: boolean; // 批注是否已解决
}>();

const emit = defineEmits<{
  (e: "expand", count: number): void;
  (e: "collapse"): void;
  (e: "reply", replyId: string, authorName: string): void;
  (e: "quote", replyId: string, authorName: string, content: string): void;
  (e: "quote-click", replyId: string): void;
  (e: "updated"): void;
}>();

const virtualListRef = ref<InstanceType<typeof DynamicVirtualList>>();
const expandedRepliesCount = ref(3); // 默认显示3条回复
const DEFAULT_REPLY_COUNT = 3;
const LOAD_MORE_COUNT = 3;
const virtualListThreshold = 10; // 超过10条回复才使用虚拟列表

// 获取可见的回复列表（按最新在前排序）
const visibleReplies = computed(() => {
  if (!props.replies?.length) return [];

  // 按时间倒序排列（最新的在前）
  const sortedReplies = [...props.replies].sort((a, b) => {
    const timeA = new Date(a.createdAt).getTime();
    const timeB = new Date(b.createdAt).getTime();
    return timeB - timeA; // 降序排列
  });

  return sortedReplies.slice(0, expandedRepliesCount.value);
});

// 判断是否应该显示展开按钮
const shouldShowExpandButton = computed(() => {
  if (!props.replies?.length) return false;
  return props.replies.length > DEFAULT_REPLY_COUNT;
});

// 判断是否所有回复都已显示
const isAllRepliesVisible = computed(() => {
  if (!props.replies?.length) return false;
  return expandedRepliesCount.value >= props.replies.length;
});

// 可见的回复数量
const visibleCount = computed(() => expandedRepliesCount.value);

// 展开更多回复
const handleExpandReplies = () => {
  if (!props.replies?.length) return;
  const newCount = Math.min(
    expandedRepliesCount.value + LOAD_MORE_COUNT,
    props.replies.length
  );
  expandedRepliesCount.value = newCount;
  emit("expand", newCount);
};

// 收起回复
const handleCollapseReplies = () => {
  expandedRepliesCount.value = DEFAULT_REPLY_COUNT;
  emit("collapse");
};

// 处理回复
const handleReply = (replyId: string, authorName: string) => {
  emit("reply", replyId, authorName);
};

// 处理引用回复
const handleQuote = (replyId: string, authorName: string, content: string) => {
  emit("quote", replyId, authorName, content);
};

// 处理点击引用
const handleQuoteClick = (replyId: string) => {
  emit("quote-click", replyId);
};

// 处理更新
const handleUpdated = () => {
  emit("updated");
};

// 组件挂载状态
let isComponentMounted = true;

// 滚动到指定的回复
const scrollToReply = async (replyId: string) => {
  // 确保回复可见（展开）
  if (props.replies && props.replies.length > 0) {
    // 使用与 visibleReplies 相同的排序逻辑
    const sortedReplies = [...props.replies].sort((a, b) => {
      const timeA = new Date(a.createdAt).getTime();
      const timeB = new Date(b.createdAt).getTime();
      return timeB - timeA;
    });
    const replyIndex = sortedReplies.findIndex((r) => r.id === replyId);

    if (replyIndex === -1) {
      console.warn(`Reply with id "${replyId}" not found`);
      return;
    }

    // 如果回复索引大于等于默认显示数量，需要展开
    if (replyIndex >= DEFAULT_REPLY_COUNT) {
      // 计算需要展开到多少条才能看到目标回复
      const targetCount = replyIndex + 1;
      let currentCount = expandedRepliesCount.value;

      // 循环展开直到目标回复可见
      while (currentCount < targetCount && isComponentMounted) {
        handleExpandReplies();
        currentCount = Math.min(
          currentCount + LOAD_MORE_COUNT,
          props.replies.length
        );
        // 等待DOM更新
        await nextTick();
        if (!isComponentMounted) return;
        await new Promise((resolve) => {
          const timer = setTimeout(resolve, 50);
          if (!isComponentMounted) {
            clearTimeout(timer);
          }
        });

        // 如果已经展开到最大数量，退出循环
        if (currentCount >= props.replies.length) {
          break;
        }
      }
    }
  }

  if (!isComponentMounted) return;

  // 等待DOM完全更新后再滚动
  await nextTick();
  if (!isComponentMounted) return;
  await nextTick();
  if (!isComponentMounted) return;
  await new Promise((resolve) => {
    const timer = setTimeout(resolve, 150);
    if (!isComponentMounted) {
      clearTimeout(timer);
    }
  });

  // 使用DOM API滚动到回复
  const replyElement = document.querySelector(
    `[data-reply-id="${replyId}"]`
  ) as HTMLElement;
  if (replyElement) {
    replyElement.scrollIntoView({
      behavior: "smooth",
      block: "center",
    });
  } else {
    console.warn(`Reply element with id "${replyId}" not found in DOM`);
  }
};

// 组件卸载时清理
onBeforeUnmount(() => {
  isComponentMounted = false;
});

// 暴露方法供父组件调用
defineExpose({
  expandReplies: handleExpandReplies,
  collapseReplies: handleCollapseReplies,
  scrollToReply,
});
</script>

<style lang="scss" scoped>
.comment-replies {
  margin-top: 12px;
  padding-top: 12px;
  padding-left: 24px; // 添加缩进以区分批注和回复
  border-left: 2px solid var(--comment-border-color); // 左侧边框区分

  // 虚拟列表容器样式
  :deep(.virtual-list-container) {
    max-height: 400px; // 限制最大高度
  }
}

.reply-expand-actions {
  margin-top: 12px;
  padding-top: 8px;
  text-align: center;
}

:deep(.highlighted-reply) {
  background: linear-gradient(
    to right,
    var(--comment-highlight-bg-start),
    var(--comment-highlight-bg-end)
  ) !important;
  box-shadow: 0 0 0 2px var(--comment-highlight-shadow);
  animation: highlight-flash 1.5s ease-in-out;
  border-radius: 6px;
  padding: 2px;
  margin: -2px;
}

@keyframes highlight-flash {
  0% {
    background: linear-gradient(
      to right,
      var(--comment-highlight-bg-start),
      var(--comment-highlight-bg-end)
    );
    box-shadow: 0 0 0 3px var(--comment-highlight-shadow);
    transform: scale(1.01);
  }
  50% {
    background: linear-gradient(
      to right,
      var(--comment-highlight-bg-start),
      var(--comment-highlight-bg-end)
    );
    box-shadow: 0 0 0 2px var(--comment-highlight-shadow);
  }
  100% {
    background: linear-gradient(
      to right,
      var(--comment-highlight-bg-start),
      var(--comment-highlight-bg-end)
    );
    box-shadow: 0 0 0 2px var(--comment-highlight-shadow);
    transform: scale(1);
  }
}
</style>
